# !/usr/bin/env python3

import os
import sys
import argparse
import hashlib

from pathlib import Path
from distutils.dir_util import copy_tree
from datetime import datetime

parser = argparse.ArgumentParser(prog='quaver',
                                usage='%(prog)s path destination [--branch]',
                                description='Backup to external drive.')

parser.add_argument('source_path',
                    type=str,
                    help='Source path input.')

parser.add_argument('destination_path',
                    type=str,
                    help='Destination path input.')

parser.add_argument('--commit',
                    type=str,
                    help='Commit message.')

parser.add_argument('--branch',
                    type=str,
                    help='Branch input.')

# https://stackoverflow.com/a/54477583
def md5_update_from_dir(directory, hash):
    assert Path(directory).is_dir()
    for path in sorted(Path(directory).iterdir(), key=lambda p: str(p).lower()):
        hash.update(path.name.encode())
        if path.is_file():
            with open(path, 'rb') as f:
                for chunk in iter(lambda: f.read(4096), b''):
                    hash.update(chunk)
        elif path.is_dir():
            hash = md5_update_from_dir(path, hash)
    return hash


def md5_dir(directory):
    return md5_update_from_dir(directory, hashlib.md5()).hexdigest()

def main():
    now = datetime.now()
    current_date = now.strftime('%m-%d-%Y')

    args = parser.parse_args()
    source_path_input = args.source_path
    destination_path_input = args.destination_path
    commit_input = args.commit
    branch_input = args.branch
    
    if branch_input == None:
        branch_input = 'master'

    if not os.path.isdir(source_path_input):
        print('The source path specified does not exist')
        sys.exit()
    elif not os.path.isdir(destination_path_input):
        print('The destination path specified does not exist')
        sys.exit()

    if commit_input == None:
        copy_tree(source_path_input, destination_path_input + '//' + branch_input + '//' + current_date + '_' + md5_dir(source_path_input))
    else:
        copy_tree(source_path_input, destination_path_input + '//' + branch_input + '//' + commit_input + '_' + current_date + '_' + md5_dir(source_path_input))

if __name__ == '__main__':
    main()